package com.share.rabbitmq.topic;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DeliverCallback;
import com.share.rabbitmq.RabbitMQConnection;

import java.util.HashMap;
import java.util.Map;

/**
 * @desc:topic交换机消费者
 * @author:caifan
 * @date:2020/3/1
 */
public class TopicExchangeConsumer {

    public static void main(String[] args) throws Exception {
        Connection connect = RabbitMQConnection.connect();
        //创建channel
        Channel channel = connect.createChannel();
//        simple(channel);
        bindExchange(channel);
        dlxExchange(channel);

    }

    /**
     * 死信绑定
     * @param channel
     * @throws Exception
     */
    private static void dlxExchange(Channel channel) throws Exception {
        String exchangeName = "my.dlx.topicExchange";
        String queueName = "my.dlx.queue";
        String routing_key1 = "my.dlx.topic.abc";

        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,false,false, null);
        channel.queueDeclare(queueName, false, false, false, null);
        channel.queueBind(queueName, exchangeName, "#");//此处设置#则任意匹配，注意此处使用的是topic exchange
        /*DeliverCallback deliverCallback = (conuserTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("message:" + message);
        };
        channel.basicConsume(queueName, deliverCallback, consumerTag -> {});*/
    }

    /**
     * 原有队列绑定
     * @param channel
     * @throws Exception
     */
    private static void bindExchange(Channel channel) throws Exception {
        String exchangeName = "my.topicExchange";
        String queueName = "my.queue";
        String routing_key1 = "my.topic.abc";

        String dlxExchangeName = "my.dlx.topicExchange";
        String dlxQueueName = "my.dlx.queue";
        String dlxRouting_key1 = "my.dlx.topic.abc";
        Map<String, Object> argMap = new HashMap<>();
        argMap.put("x-dead-letter-exchange", dlxExchangeName);

        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false, null);
        channel.queueDeclare(queueName, true, false, false, argMap);
        channel.queueBind(queueName, exchangeName, routing_key1);
        DeliverCallback deliverCallback = (conuserTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("message:" + message);
        };
        channel.basicConsume(queueName, deliverCallback, consumerTag -> {});
    }

    /**
     * 简单消费消息
     * @param channel
     * @throws Exception
     */
    private static void simple(Channel channel) throws Exception {
        String exchangeName = "my.topicExchange";
        String queueName = "my.topicQueue";
        /**
         * 声明一个交换机
         * exchange:交换机的名称
         * type:交换机的类型 常见的有direct,fanout,topic等
         * durable:设置是否持久化。durable设置为true时表示持久化，反之非持久化.持久化可以将交换器存入磁盘，在服务器重启的时候不会丢失相关信息
         * autodelete:设置是否自动删除。autoDelete设置为true时，则表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定，之后，所有与这个交换器绑定的队列或者交换器都与此解绑。
         * 不能错误的理解—当与此交换器连接的客户端都断开连接时，RabbitMq会自动删除本交换器
         * arguments:其它一些结构化的参数，比如：alternate-exchange
         */
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,true,null);

        /**
         * 声明一个队列
         * durable:表示rabbitmq关闭删除队列
         * autodelete:表示没有程序和队列建立连接 那么就会自动删除队列
         *
         */
        channel.queueDeclare(queueName,true,false,false,null);

        //声明绑定关系 * 匹配单个 #匹配多个
        String bindingStr = "my.*";
        /**
         * 队里和交换机绑定
         */
        channel.queueBind(queueName,exchangeName, bindingStr);

        DeliverCallback deliverCallback = (conuserTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("message:" + message);
        };
        channel.basicConsume(queueName, deliverCallback, consumerTag -> {});
    }
}
